﻿using System.Collections.Generic;
using System.ComponentModel;
using System.Windows.Forms;

namespace Maydew.Windows.Forms.Controls.FlexiCell
{
    public partial class FlexiCellControl
    {
        #region " 合并单元格 "
        /// <summary>
        /// 合并选中单元格。
        /// </summary>
        public void MergeCells()
        {
            int srow;
            int erow;
            string scol;
            string ecol;
            GetCellRectangle(_focusedCells, out srow, out scol, out erow, out ecol);
            MergeCells(srow, scol, erow, ecol);
        }
        /// <summary>
        /// 合并指定单元格。
        /// </summary>
        /// <param name="startRowIndex">开始行。</param>
        /// <param name="startColumnName">开始列。</param>
        /// <param name="endRowIndex">结束行。</param>
        /// <param name="endColumnName">结束列。</param>
        public void MergeCells(int startRowIndex, string startColumnName, int endRowIndex, string endColumnName)
        {
            int startColumnIndex = _columns.IndexOf(_columns[startColumnName]);
            int endColumnIndex = _columns.IndexOf(_columns[endColumnName]);
            MergeCells(startRowIndex, startColumnIndex, endRowIndex, endColumnIndex);
        }
        /// <summary>
        /// 合并指定单元格。
        /// </summary>
        /// <param name="startRowIndex">开始行。</param>
        /// <param name="startColumnName">开始列。</param>
        /// <param name="endRowIndex">结束行。</param>
        /// <param name="endColumnName">结束列。</param>
        public void MergeCells(int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex)
        {
            if (startRowIndex > endRowIndex)
            {
                int temp = startRowIndex;
                startRowIndex = endRowIndex;
                endRowIndex = temp;
            }
            if (startColumnIndex > endColumnIndex)
            {
                int temp = startColumnIndex;
                startColumnIndex = endColumnIndex;
                endColumnIndex = temp;
            }
            Cell mainCell = _cells[startRowIndex, _columns[startColumnIndex].ColumnName];
            mainCell.Merged = true;
            for (int r = startRowIndex; r <= endRowIndex; r++)
            {
                for (int c = startColumnIndex; c <= endColumnIndex; c++)
                {
                    Cell cell = _cells[r, _columns[c].ColumnName];
                    if (cell.Merged) UnmergeCells(cell);
                    cell.MainCell = mainCell;
                    cell.Visible = false;
                    cell.Merged = true;
                    if (mainCell != cell) mainCell.MergedCells.Add(cell);
                }
            }
            mainCell.Width = GetRangeWidth(startColumnIndex, endColumnIndex);
            mainCell.Height = GetRangeHeight(startRowIndex, endRowIndex);
            mainCell.Visible = true;

            base.Refresh();
        }
        #endregion

        #region " 拆分单元格 "
        /// <summary>
        /// 拆分选中单元格。
        /// </summary>
        public void UnmergeCells()
        {
            int srow;
            int erow;
            string scol;
            string ecol;
            GetCellRectangle(_focusedCells, out srow, out scol, out erow, out ecol);
            UnmergeCells(srow, scol, erow, ecol);
        }
        /// <summary>
        /// 拆分指定单元格。
        /// </summary>
        /// <param name="startRowIndex">开始行。</param>
        /// <param name="startColumnIndex">开始列。</param>
        /// <param name="endRowIndex">结束行。</param>
        /// <param name="endColumnIndex">结束列。</param>
        public void UnmergeCells(int startRowIndex, string startColumnName, int endRowIndex, string endColumnName)
        {
            int startColumnIndex = _columns.IndexOf(_columns[startColumnName]);
            int endColumnIndex = _columns.IndexOf(_columns[endColumnName]);
            UnmergeCells(startRowIndex, startColumnIndex, endRowIndex, endColumnIndex);
        }
        /// <summary>
        /// 拆分指定单元格。
        /// </summary>
        /// <param name="startRowIndex">开始行。</param>
        /// <param name="startColumnIndex">开始列。</param>
        /// <param name="endRowIndex">结束行。</param>
        /// <param name="endColumnIndex">结束列。</param>
        public void UnmergeCells(int startRowIndex, int startColumnIndex, int endRowIndex, int endColumnIndex)
        {
            if (startRowIndex > endRowIndex)
            {
                int temp = startRowIndex;
                startRowIndex = endRowIndex;
                endRowIndex = temp;
            }
            if (startColumnIndex > endColumnIndex)
            {
                int temp = startColumnIndex;
                startColumnIndex = endColumnIndex;
                endColumnIndex = temp;
            }
            for (int r = startRowIndex; r <= endRowIndex; r++)
            {
                for (int c = startColumnIndex; c <= endColumnIndex; c++)
                {
                    Cell cell = _cells[r, _columns[c].ColumnName];
                    UnmergeCells(cell);
                }
            }
            base.Refresh();
        }
        /// <summary>
        /// 拆分指定单元格。
        /// </summary>
        /// <param name="cell">单元格。</param>
        public void UnmergeCells(Cell cell)
        {
            cell.Visible = true;
            cell.Merged = false;
            cell.MainCell = null;
            cell.MergedCells.Clear();
            cell.Width = _columns[cell.ColumnName].Width;
            cell.Height = _rows[cell.RowIndex].Height;
        }
        #endregion

        #region " Range "
        /// <summary>
        /// 获取单元格矩形。
        /// </summary>
        /// <param name="cells">单元格集合。</param>
        /// <param name="startRowIndex">开始行返回值。</param>
        /// <param name="startColumnName">开始列返回值。</param>
        /// <param name="endRowIndex">结束行返回值。</param>
        /// <param name="endColumnName">结束列返回值。</param>
        protected virtual void GetCellRectangle(List<Cell> cells, out int startRowIndex, out string startColumnName, out int endRowIndex, out string endColumnName)
        {
            int srow = int.MaxValue;
            int erow = int.MinValue;
            int scol = int.MaxValue;
            int ecol = int.MinValue;
            foreach (Cell cell in cells)
            {
                int msrow = cell.RowIndex, merow = cell.RowIndex;
                string mscol = cell.ColumnName, mecol = cell.ColumnName;
                if (cell.MergedCells.Count > 0)
                {
                    GetCellRectangle(cell.MergedCells, out msrow, out mscol, out merow, out mecol);
                    msrow = cell.RowIndex;
                    mscol = cell.ColumnName;
                }
                if (srow > msrow) srow = msrow;
                if (erow < merow) erow = merow;
                int c = _columns.IndexOf(mscol);
                if (scol > c) scol = c;
                c = _columns.IndexOf(mecol);
                if (ecol < c) ecol = c;
            }
            startRowIndex = srow;
            endRowIndex = erow;
            startColumnName = _columns[scol].ColumnName;
            endColumnName = _columns[ecol].ColumnName;
        }
        /// <summary>
        /// 获取单元格矩形宽度。
        /// </summary>
        /// <param name="startColumnIndex">开始列。</param>
        /// <param name="endColumnIndex">结束列。</param>
        /// <returns>返回单元格矩形宽度。</returns>
        protected virtual int GetRangeWidth(int startColumnIndex, int endColumnIndex)
        {
            int left = _columns[startColumnIndex].Bounds.Left;
            int right = _columns[endColumnIndex].Bounds.Right;
            return right - left;
        }
        /// <summary>
        /// 获取单元格矩形高度。
        /// </summary>
        /// <param name="startRowIndex">开始行。</param>
        /// <param name="endRowIndex">结束列。</param>
        /// <returns>返回单元格矩形高度。</returns>
        protected virtual int GetRangeHeight(int startRowIndex, int endRowIndex)
        {
            int top = _rows[startRowIndex].Bounds.Top;
            int bottom = _rows[endRowIndex].Bounds.Bottom;
            return bottom - top;
        }
        #endregion
    }
}
